#include "mywinusb.h"
#include "winerror.h"
#include "QDebug"
#include "QDateTime"
#include <QUuid>

mywinusb::mywinusb(QObject *parent) : QObject(parent) {
    // 构造函数内容（如果有）
    this->userPID = 0;
    this->userVID = 0;
}

BOOL mywinusb::setUserUSBDeviceVID_PID(uint16_t vid, uint16_t pid)
{
    this->userPID = pid;
    this->userVID = vid;
    return true;
}

void mywinusb::usbErrorHandler(void)
{
  if (hDeviceHandle != INVALID_HANDLE_VALUE)
    {
      CloseHandle(hDeviceHandle);
      hDeviceHandle = INVALID_HANDLE_VALUE;
  }
  if (hWinUSBHandle != INVALID_HANDLE_VALUE)
    {
     WinUsb_Free(hWinUSBHandle);
     hWinUSBHandle = INVALID_HANDLE_VALUE;
  }
}
BOOL mywinusb::getUSBConnectState(void)
{
    return this->connectResult;
}

void printGUID(const GUID& guid)
{
    // 使用 QUuid 构造函数从 GUID 创建一个 UUID 对象
    QUuid uuid(
        guid.Data1,
        guid.Data2,
        guid.Data3,
        guid.Data4[0],
        guid.Data4[1],
        guid.Data4[2],
        guid.Data4[3],
        guid.Data4[4],
        guid.Data4[5],
        guid.Data4[6],
        guid.Data4[7]
    );

    // 使用 qDebug 打印 UUID 字符串
    qDebug() << "GUID:" << uuid.toString();
}

// 函数用于将QString格式的UUID转换为GUID结构
BOOL mywinusb::setUserUSBDeviceGUID(QString userguid)
{
    bool ret = false;
    GUID guidDeviceInterface;

    // 分割字符串
    QStringList parts = userguid.split('-');
    if (parts.size() != 5) {
        // 错误处理：不是有效的UUID格式
        usbErrorPrint(__FILE__, __LINE__);
        return ret;
    }
    // 将字符串转换为整数
    bool ok;
    guidDeviceInterface.Data1 = parts[0].toUInt(&ok, 16);
    if (!ok)
    {
        usbErrorPrint(__FILE__, __LINE__);
        return ret;
    }

    guidDeviceInterface.Data2 = parts[1].toUShort(&ok, 16);
    if (!ok)
    {
        usbErrorPrint(__FILE__, __LINE__);
        return ret;
    }

    guidDeviceInterface.Data3 = parts[2].toUShort(&ok, 16);
    if (!ok)
    {
        usbErrorPrint(__FILE__, __LINE__);
        return ret;
    }

    guidDeviceInterface.Data4[0] = parts[3].mid(0,2).toUInt(&ok, 16);
    guidDeviceInterface.Data4[1] = parts[3].mid(2,2).toUInt(&ok, 16);
    for (int i = 0; i < 6; ++i) {
        guidDeviceInterface.Data4[i+2] = parts[4].mid(i * 2, 2).toUInt(&ok, 16);
        if (!ok)
        {
            usbErrorPrint(__FILE__, __LINE__);
            return ret;
        }
    }
    ret = true;
    this->guidDeviceInterface = guidDeviceInterface;
    return ret;
}

void mywinusb::usbErrorPrint(QString file, int line)
{

  DWORD  err = GetLastError();
  this->connectResult = false;
  QString errinfo = QString(file + QString("Line: %1, Error: %2\n").arg(line).arg(err));
  usbErrorHandler();

  emit this->printErrorInfo(errinfo);
  qDebug() << errinfo;
}

void mywinusb::usbErrorPrint(QString err)
{
  emit this->printErrorInfo(err);
}



BOOL mywinusb::setUSBDeviceConnect(void)
{
  BOOL bResult = false;

  do
  {
      if(this->userVID ||  this->userPID)
      {
        qDebug() << "find usb device use pvid!";
        bResult = GetDeviceHandleBy_VID_PID(this->userVID, this->userPID);
      }
      else
      {
        qDebug() << "find usb device use guid!";
        bResult = GetDeviceHandleBy_GUID(&this->guidDeviceInterface);
      }

      if (!bResult)
      {
        usbErrorPrint("获取设备句柄错误");
        break;
      }
      bResult = GetWinUSBHandle();
      if (!bResult)
      {
        usbErrorPrint("获取WinUsb句柄错误");
        break;
      }
      bResult = GetUSBDeviceSpeed();
      if (!bResult)
      {
          usbErrorPrint("获取GetUSBDeviceSpeed句柄错误");
        break;
      }
      // 选择配置值 1
//      WinUsb_SetConfiguration(this->hWinUSBHandle, 1);

      bResult = QueryDeviceEndpoints();
      if (!bResult)
      {
          usbErrorPrint("获取QueryDeviceEndpoints句柄错误");
        break;
      }
  }while(0);

  if(bResult == false)
  {
    //usbErrorPrint(__FILE__, __LINE__);
  }
  usbErrorPrint("USB设备检测完成");
  this->connectResult = bResult;
  return bResult;
}

BOOL mywinusb::GetDeviceHandleBy_GUID(CONST GUID *InterfaceClassGuid)
{
  BOOL bResult = TRUE;
  HDEVINFO hDeviceInfo;
  SP_DEVINFO_DATA DeviceInfoData;
  SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
  PSP_DEVICE_INTERFACE_DETAIL_DATA pInterfaceDetailData = NULL;

  ULONG requiredLength = 0;
  LPTSTR lpDevicePath = NULL;
  DWORD index = 0;

  hDeviceInfo = SetupDiGetClassDevs(InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

  if (hDeviceInfo == INVALID_HANDLE_VALUE)
  {
    usbErrorPrint(__FILE__, __LINE__);
    goto done;
  }

  DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

  for (index = 0; SetupDiEnumDeviceInfo(hDeviceInfo, index, &DeviceInfoData); index++)
  {
    if (lpDevicePath)
    {
      LocalFree(lpDevicePath);
    }
    if (pInterfaceDetailData)
    {
      LocalFree(pInterfaceDetailData);
    }

    deviceInterfaceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
    bResult = SetupDiEnumDeviceInterfaces(hDeviceInfo, &DeviceInfoData, InterfaceClassGuid, 0, &deviceInterfaceData);

    if (GetLastError() == ERROR_NO_MORE_ITEMS)
    {
        qDebug() << "ERROR_NO_MORE_ITEMS";
        break;
    }

    if (!bResult)
    {
      usbErrorPrint(__FILE__, __LINE__);
      goto done;
    }

    bResult = SetupDiGetDeviceInterfaceDetail(hDeviceInfo, &deviceInterfaceData, NULL, NULL, &requiredLength, NULL);

    if (!bResult)
    {
      if ((ERROR_INSUFFICIENT_BUFFER == GetLastError()) && (requiredLength > 0))
      {
        pInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, requiredLength);

        if (!pInterfaceDetailData)
        {
          qDebug() << QString("Error allocating memory for the device detail buffer.\n");
          goto done;
        }
      }
      else
      {
        usbErrorPrint(__FILE__, __LINE__);
        goto done;
      }
    }

    pInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

    bResult = SetupDiGetDeviceInterfaceDetail(hDeviceInfo, &deviceInterfaceData, pInterfaceDetailData, requiredLength, NULL, &DeviceInfoData);

    if (!bResult)
    {
      usbErrorPrint(__FILE__, __LINE__);
      goto done;
    }

    size_t nLength = wcslen(pInterfaceDetailData->DevicePath) + 1;

    lpDevicePath = (TCHAR*)LocalAlloc(LPTR, nLength * sizeof(TCHAR));

    StringCchCopy(lpDevicePath, nLength, pInterfaceDetailData->DevicePath);

    lpDevicePath[nLength - 1] = 0;
  }

  if (!lpDevicePath)
  {
    qDebug() << "index:" << index;
    usbErrorPrint(__FILE__, __LINE__);
    bResult = false;
    goto done;
  }

  qDebug() << QString("Device path: %1").arg(lpDevicePath);
  this->hDeviceHandle = CreateFile(lpDevicePath,
                    GENERIC_READ | GENERIC_WRITE,
                    FILE_SHARE_READ | FILE_SHARE_WRITE,
                    NULL,
                    OPEN_EXISTING,
                    FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL,
                    NULL);

  if (this->hDeviceHandle == INVALID_HANDLE_VALUE)
  {
    usbErrorPrint(__FILE__, __LINE__);
    goto done;
  }

done:
  LocalFree(lpDevicePath);
  LocalFree(pInterfaceDetailData);
  SetupDiDestroyDeviceInfoList(hDeviceInfo);

  return bResult;
}

BOOL  mywinusb::GetDeviceHandleBy_VID_PID(uint16_t vendorId, uint16_t productId)
{
    BOOL bResult = TRUE;
    HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
    SP_DEVICE_INTERFACE_DATA deviceInterfaceData = {};
    PSP_DEVICE_INTERFACE_DETAIL_DATA pInterfaceDetailData = NULL;

    ULONG requiredLength = 0;
    LPTSTR lpDevicePath = NULL;
    DWORD index = 0;
    uint16_t vidi = 0;
    uint16_t pidi = 0;
    // Get information about all the installed devices for the specified
    // device interface class.
    hDeviceInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

    if (hDeviceInfo == INVALID_HANDLE_VALUE)
    {
        usbErrorPrint(__FILE__, __LINE__);
        goto done;
    }

    //Enumerate all the device interfaces in the device information set.
    SP_DEVINFO_DATA DeviceInfoData;
    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

    for (index = 0; SetupDiEnumDeviceInfo(hDeviceInfo, index, &DeviceInfoData); index++)
    {
        //Reset for this iteration
        if (lpDevicePath)
        {
            LocalFree(lpDevicePath);
        }
        if (pInterfaceDetailData)
        {
            LocalFree(pInterfaceDetailData);
        }

        deviceInterfaceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);

        //Get information about the device interface.
        bResult = SetupDiEnumDeviceInterfaces(hDeviceInfo, &DeviceInfoData, &GUID_DEVINTERFACE_USB_DEVICE, 0, &deviceInterfaceData);

        // Check if last item
        if (GetLastError() == ERROR_NO_MORE_ITEMS)
        {
            usbErrorPrint(__FILE__, __LINE__);
            break;
        }

        //Check for some other error
        if (!bResult)
        {
           usbErrorPrint(__FILE__, __LINE__);
            goto done;
        }

        // 获取设备接口的详细信息,调两遍是因为第一次不知道具体大小，
        bResult = SetupDiGetDeviceInterfaceDetail(hDeviceInfo, &deviceInterfaceData, NULL, 0, &requiredLength, NULL);

        //Check for some other error
        if (!bResult)
        {
            if ((ERROR_INSUFFICIENT_BUFFER == GetLastError()) && (requiredLength > 0))
            {
                //we got the size, allocate buffer 获取大小后申请内存
                pInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, requiredLength);

                if (!pInterfaceDetailData)
                {
                    usbErrorPrint(__FILE__, __LINE__);
                    goto done;
                }
            }
            else
            {
                usbErrorPrint(__FILE__, __LINE__);
                goto done;
            }
        }
        //get the interface detailed data
        if (pInterfaceDetailData == NULL)
        {
            usbErrorPrint(__FILE__, __LINE__);
            goto done;
        }

        pInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

        //Now call it with the correct size and allocated buffer
        bResult = SetupDiGetDeviceInterfaceDetail(hDeviceInfo, &deviceInterfaceData, pInterfaceDetailData, requiredLength, NULL, &DeviceInfoData);

        //Check for some other error
        if (!bResult)
        {
            usbErrorPrint(__FILE__, __LINE__);
            goto done;
        }
        //copy device path
        size_t nLength = wcslen((const wchar_t*)pInterfaceDetailData->DevicePath) + 1;
        lpDevicePath = (TCHAR*)LocalAlloc(LPTR, nLength * sizeof(TCHAR));
        StringCchCopy(lpDevicePath, nLength, pInterfaceDetailData->DevicePath);
        lpDevicePath[nLength - 1] = 0;
#ifdef _UNICODE
         // Unicode模式
         // wprintf(_T("%ls\n"), lpDevicePath);
#else
        // ANSI模式
        printf(_T("%s\n"), lpDevicePath);
#endif
        // 获取并打印VID和PID
        TCHAR hardwareId[256] = {};
        if (SetupDiGetDeviceRegistryProperty(hDeviceInfo, &DeviceInfoData, SPDRP_HARDWAREID, NULL, (PBYTE)hardwareId, sizeof(hardwareId), NULL))
        {
            // 从Hardware ID中解析VID和PID
            TCHAR* vidPos = _tcsstr(hardwareId, _T("VID_"));
            TCHAR* pidPos = _tcsstr(hardwareId, _T("PID_"));
            if (vidPos && pidPos)
            {
                TCHAR vid[5] = { 0 };
                TCHAR pid[5] = { 0 };
                _tcsncpy_s(vid, vidPos + 4, 4);
                _tcsncpy_s(pid, pidPos + 4, 4);
                _stscanf_s(vid, _T("%4hx"), &vidi);
                _stscanf_s(pid, _T("%4hx"), &pidi);

                if (vidi == vendorId && pidi == productId)
                {
//                    wprintf(_T("%ls\n"), lpDevicePath);
//                    _tprintf(_T("VID:0x%04X PID:0x%04X.\n"), vidi, pidi);
                    break;
                }
            }
        }
    }//for (index = 0; SetupDiEnumDeviceInfo(hDeviceInfo, index, &DeviceInfoData); index++)



    if (!lpDevicePath || !(vidi == vendorId && pidi == productId))
    {
        qDebug() << "vidi:" << vidi << "pidi:" << pidi;
        usbErrorPrint(__FILE__, __LINE__);
        goto done;
    }
    //Open the device 创建文件句柄
    qDebug() << QString("Device path: %1").arg(lpDevicePath);
    this->hDeviceHandle = CreateFile(   lpDevicePath,
                                        GENERIC_READ | GENERIC_WRITE,
                                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                                        NULL,
                                        OPEN_EXISTING,
                                        FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL,
                                        NULL);

    if (this->hDeviceHandle == INVALID_HANDLE_VALUE)
    {
        usbErrorPrint(__FILE__, __LINE__);
        goto done;
    }

done:
    LocalFree(lpDevicePath);
    LocalFree(pInterfaceDetailData);
    bResult = SetupDiDestroyDeviceInfoList(hDeviceInfo);//销毁列表

    return bResult;
}

BOOL mywinusb::GetWinUSBHandle(void)
{
  if (this->hDeviceHandle == INVALID_HANDLE_VALUE)
  {
    return FALSE;
  }
  this->hWinUSBHandle = INVALID_HANDLE_VALUE;
  BOOL bResult = WinUsb_Initialize(this->hDeviceHandle, &this->hWinUSBHandle);
  if (!bResult)
  {
    usbErrorPrint(__FILE__, __LINE__);
  }
  return bResult;
}

BOOL mywinusb::GetUSBDeviceSpeed(void)
{
  if (this->hWinUSBHandle == INVALID_HANDLE_VALUE)
  {
    return FALSE;
  }

  BOOL bResult = TRUE;
  ULONG length = sizeof(UCHAR);
  bResult = WinUsb_QueryDeviceInformation(this->hWinUSBHandle, DEVICE_SPEED, &length, &this->DeviceSpeed);
  if (bResult)
  {
      if (this->DeviceSpeed == LowSpeed)
      {
        qDebug() << QString("Device speed: %1 (Low speed).\n").arg(this->DeviceSpeed);
      }
      else if (this->DeviceSpeed == FullSpeed)
      {
        qDebug() << QString("Device speed: %1 (Full speed).\n").arg(this->DeviceSpeed);
      }
      else if (this->DeviceSpeed == HighSpeed)
      {
        qDebug() << QString("Device speed: %1 (High speed).\n").arg(this->DeviceSpeed);
      }
      else{
        qDebug() << QString("Device speed: %1 (other speed).\n").arg(this->DeviceSpeed);
      }
  }
  else{
      usbErrorPrint(__FILE__, __LINE__);
  }
  return bResult;
}

BOOL mywinusb::QueryDeviceEndpoints(void)
{
    if (this->hWinUSBHandle == INVALID_HANDLE_VALUE)
    {
        return FALSE;
    }

    BOOL bResult = FALSE;

    USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
    WINUSB_PIPE_INFORMATION Pipe;

    UCHAR interfaceNum = 0;
    while(1)
    {
        ZeroMemory(&InterfaceDescriptor, sizeof(USB_INTERFACE_DESCRIPTOR));
        ZeroMemory(&Pipe, sizeof(WINUSB_PIPE_INFORMATION));

        bResult = WinUsb_QueryInterfaceSettings(this->hWinUSBHandle, interfaceNum, &InterfaceDescriptor);

        if (bResult == FALSE)
        {
            if (GetLastError() == ERROR_NO_MORE_ITEMS)
            {
                bResult = TRUE;
                qDebug() << "ERROR_NO_MORE_ITEMS" << __LINE__;
                break;
            }
            else{
                usbErrorPrint(__FILE__, __LINE__);
                return bResult;
            }
        }
        interfaceNum++;

        qDebug() << "InterfaceDescriptor.bNumEndpoints:" << InterfaceDescriptor.bNumEndpoints;

        for (int index = 0; index < InterfaceDescriptor.bNumEndpoints; index++)
        {
            bResult = WinUsb_QueryPipe(this->hWinUSBHandle, 0, index, &Pipe);
            if (!bResult)
              continue;

            QString pipeID = QString::number( Pipe.PipeId, 16).toUpper().rightJustified(2, '0');
            switch (Pipe.PipeType) {
            case UsbdPipeTypeInterrupt:
                qDebug() << "Endpoint index: " << index << " Pipe type: UsbdPipeTypeInterrupt" << " Interrupt Pipe ID: " << pipeID;
                break;
            case UsbdPipeTypeControl:
                qDebug() << "Endpoint index: " << index << " Pipe type: UsbdPipeTypeControl" << " Control Pipe ID: " << pipeID;
                break;
            case UsbdPipeTypeIsochronous:
                qDebug() << "Endpoint index: " << index << " Pipe type: UsbdPipeTypeIsochronous" << " Isochronous Pipe ID: " << pipeID;
                break;
            case UsbdPipeTypeBulk:
                if(Pipe.PipeId & 0x80)
                {
                    qDebug() << "Endpoint index: " << index << " Pipe type: UsbdPipeTypeBulk"  << "In  Bulk Pipe ID: " << pipeID;
                    for (int var = 0; var < 5; ++var) {
                        if(this->PipeID.PipeInId[var] == 0){
                            this->PipeID.PipeInId[var] = Pipe.PipeId;
                            break;
                        }
                    }
                }
                else{
                    qDebug() << "Endpoint index: " << index << " Pipe type: UsbdPipeTypeBulk" << "Out Bulk Pipe ID: " << pipeID;
                    for (int var = 0; var < 5; ++var) {
                        if(this->PipeID.PipeOutId[var] == 0){
                            this->PipeID.PipeOutId[var] = Pipe.PipeId;
                            break;
                        }
                    }
                }
                break;
            default:
                break;
            }
        }
    }
    return bResult;
}

BOOL mywinusb::WriteToBulkEndpoint(UCHAR* pID, UCHAR* sendtext, ULONG wLen)
{
  if (this->hWinUSBHandle == INVALID_HANDLE_VALUE || !pID)
  {
    return FALSE;
  }
 // qDebug() << "WriteToBulkEndpoint:" << QString::number(*pID, 16).toUpper().rightJustified(2, '0') << "len:" << wLen;

  BOOL bResult = TRUE;
  ULONG cbSent = 0;
  bResult = WinUsb_WritePipe(this->hWinUSBHandle, *pID, sendtext, wLen, &cbSent, 0);
  if (!bResult)
  {
        usbErrorPrint(__FILE__, __LINE__);
  }
  return bResult;
}

int mywinusb::ReadFromBulkEndpoint(UCHAR* pID, UCHAR* readBuffer, ULONG maxLen)
{
  if (this->hWinUSBHandle == INVALID_HANDLE_VALUE)
  {
    return -1;
  }
  //qDebug() << "ReadFromBulkEndpoint:" <<  QString::number(*pID, 16).toUpper().rightJustified(2, '0');
  BOOL bResult = TRUE;
  ULONG cbRead = 0;

  OVERLAPPED overlapped;
  memset(&overlapped, 0, sizeof(OVERLAPPED));

  overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

  bResult = WinUsb_ReadPipe(this->hWinUSBHandle, *pID, readBuffer, maxLen, &cbRead, &overlapped);
  if (bResult == FALSE) {
      DWORD error = GetLastError();
      if (error != ERROR_IO_PENDING) {
          // 处理错误
          usbErrorPrint(__FILE__, __LINE__);
          return -2;
      }
  }
  // 等待操作完成
  WaitForSingleObject(overlapped.hEvent, INFINITE);
  // 获取最终的读取结果
  if (GetOverlappedResult(this->hWinUSBHandle, &overlapped, &cbRead, FALSE)) {
      // 成功读取数据
  }
  else {
      // 处理错误
  }

  CloseHandle(overlapped.hEvent); // 关闭事件句柄
  return cbRead;
}


BOOL mywinusb::ReadDatatoDefaultEndpoint(void)
{

    if (this->hWinUSBHandle == INVALID_HANDLE_VALUE)
    {
        qDebug() << __FUNCTION__ << __LINE__;
        return FALSE;
    }
    BOOL bResult = TRUE;
    WINUSB_SETUP_PACKET SetupPacket;
/* https://www.usbzh.com/article/detail-690.html    */
    SetupPacket.RequestType = 0xC0;
    SetupPacket.Request = 0x40;
    SetupPacket.Value = 0x0100;
    SetupPacket.Index = 0;
    SetupPacket.Length = 0x0000;

    UCHAR descriptor_buffer[256] = {0};
    ULONG cbSent = 0;
    QByteArray byteArray;

    bResult = WinUsb_ControlTransfer(this->hWinUSBHandle, SetupPacket, descriptor_buffer, sizeof(descriptor_buffer), &cbSent, 0);
    if(!bResult)
    {
        usbErrorPrint(__FILE__, __LINE__);
        goto done;
    }

    qDebug() << "Actual data transferred:" << cbSent;
    byteArray = QByteArray(reinterpret_cast<const char*>(descriptor_buffer), cbSent);
    qDebug() << "Data as string:" << byteArray;
done:
    return bResult;
}



BOOL mywinusb::SendDatatoDefaultEndpoint(void)
{
    if (this->hWinUSBHandle==INVALID_HANDLE_VALUE)
    {
        qDebug() << __FUNCTION__ << __LINE__;
        return FALSE;
    }
    BOOL bResult = TRUE;
    WINUSB_SETUP_PACKET SetupPacket;
/* https://www.usbzh.com/article/detail-690.html    */
    SetupPacket.RequestType = 0x40;
    SetupPacket.Request = 0x40;
    SetupPacket.Value = 0x0100;
    SetupPacket.Index = 0;
    SetupPacket.Length = 0x0000;

    QString he = "hello,world!";

    QByteArray byteArray = he.toLatin1();//最大不能超过4KB


    const unsigned char* data = reinterpret_cast<const unsigned char*>(byteArray.constData());
    int length = byteArray.size();

    ULONG cbSent = 0;


    bResult = WinUsb_ControlTransfer(this->hWinUSBHandle, SetupPacket, (UCHAR*)data, length, &cbSent, 0);
    if(!bResult)
    {
        usbErrorPrint(__FILE__, __LINE__);
        goto done;
    }

    qDebug() << "Actual data transferred:" << cbSent;



done:
    return bResult;
}

void printHex(const UCHAR *data, int length) {
    QString hexString;
    for (int i = 0; i < length; ++i) {
        // 将每个字节转换为两位十六进制字符，并添加到hexString中
        hexString.append(QString("%1 ").arg(data[i], 2, 16, QChar('0')).toUpper());
    }
    qDebug() << "Hexadecimal representation:" << hexString.trimmed(); // trimmed()移除末尾多余的空格
}

BOOL mywinusb::GetUserInterfaceConfig(void)
{
    if (this->hWinUSBHandle == INVALID_HANDLE_VALUE)
    {
        qDebug() << __FUNCTION__ << __LINE__;
        return FALSE;
    }
    BOOL bResult = TRUE;

    /* https://www.usbzh.com/article/detail-690.html    */
    UCHAR data[1024];
    ULONG cbSent = 0;

    bResult = WinUsb_ControlTransfer(this->hWinUSBHandle, SetupPacket, (UCHAR*)data, SetupPacket.Length, &cbSent, 0);
    if(!bResult)
    {
        usbErrorPrint(__FILE__, __LINE__);
        goto done;
    }
    qDebug() << "Actual data transferred:" << cbSent << "data:";
    printHex(data, data[0]);

done:
    return bResult;
}
